package fileoperate

import (
	"context"
	"github.com/spf13/afero"
	"gitlab.local/DO-module/new-filemanage-module/src/service/file_safeBox"
	"gitlab.local/DO-module/new-filemanage-module/src/service/user"
	"gitlab.local/TerraMaster/tos-modules/core/acl"
	"gitlab.local/TerraMaster/tos-modules/database"
	fileopreate2 "gitlab.local/TerraMaster/tos-modules/fileoperate"
	"sync"
	"time"

	"gitlab.local/golibrary/utils"
)

type Folders struct {
	Total int           `json:"total"`
	Data  []FoldersInfo `json:"data"`
}

type FoldersInfoAll struct {
	FoldersInfo
	SuperAdmin string `json:"super_admin"` //超级管理员
}

type CapacityStatistics struct {
	status         uint8 //0进行中,1完成
	capacity       int64 //容量（B）
	cancelFunc     *context.CancelFunc
	timer          *time.Timer
	delChan        chan struct{}
	FileQuantity   int `json:"file_quantity"`   //文件夹下总文件数量
	FolderQuantity int `json:"folder_quantity"` //文件夹下总文件夹数量
}

type UserAttrs struct {
	acl.Attrs
	Groups   []string `json:"groups"`    //用户属于哪几个组
	GroupAcl string   `json:"group_acl"` //来自用户组的权限
}

// FoldersInfo 文件信息格式
type FoldersInfo struct {
	Name             string        `json:"name"`                         //名称
	Path             string        `json:"path"`                         //路径
	Volume           string        `json:"volume"`                       //卷
	VolumePath       string        `json:"volume_path"`                  //卷+路径
	Icon             string        `json:"icon,omitempty"`               //图标路径
	ATime            string        `json:"a_time"`                       //访问时间
	MTime            string        `json:"m_time"`                       //修改时间
	CTime            string        `json:"c_time"`                       //创建时间
	FType            utils.FType   `json:"f_type"`                       //类型(folder、file、app_link、oexe、music、video、image)
	Size             int64         `json:"size"`                         //字节B
	SizeFriendly     string        `json:"size_friendly"`                //文件大小(友好)
	Users            []UserAttrs   `json:"users,omitempty"`              //所有者s
	Groups           []acl.Attrs   `json:"groups,omitempty"`             //所属组s
	Owner            string        `json:"owner,omitempty"`              //所有者
	OwnerId          string        `json:"owner_id,omitempty"`           //所有者id
	Group            string        `json:"group,omitempty"`              //所属组
	GroupId          string        `json:"group_id,omitempty"`           //所属组id
	Link             string        `json:"link,omitempty"`               //连接地址(只有为appLink类型的文件才有此属性)
	Permission       string        `json:"permission"`                   //用户拥有权限(rwx)
	IsHome           int8          `json:"is_home,omitempty"`            //是否home目录,1是，2否
	FRealType        string        `json:"f_real_type"`                  //文件真实类型
	IsCollect        bool          `json:"is_collect"`                   //是否收藏
	IsShare          bool          `json:"is_share"`                     //是否分享
	Level            int           `json:"level"`                        //层级
	Hidden           bool          `json:"hidden"`                       //是否隐藏
	FileQuantity     int           `json:"file_quantity"`                //文件夹下总文件数量
	FolderQuantity   int           `json:"folder_quantity"`              //文件夹下总文件夹数量
	FileSystem       string        `json:"file_system"`                  //文件系统格式
	ChildFoldersInfo []FoldersInfo `json:"child_folders_info,omitempty"` //子文件信息
}

type TaskParams struct {
	Uname      string
	Size       int64 //任务总大小(B)
	TType      fileopreate2.FileOperation
	Paths      []string
	ToPath     string
	SafeBoxSrc string
	Coding     string
	UnType     fileopreate2.FileDecompress
}

type ListGetter interface {
	GetShareList() ([]*fileopreate2.FoldersInfo, error)
	GetShareOfUsb() ([]*fileopreate2.FoldersInfo, error)
}

type Getter interface {
	ListGetter
	GetFolders(dir string, limit, page int, rule fileopreate2.OrderRule, order, noShowHiddenFolder bool, safeBoxSrc string, safeBoxStatus bool) (*fileopreate2.Folders, error)
	GetFoldersFilter(dir, username string, ctx context.Context) (*fileopreate2.FoldersInfoAll, error)
	GetFolder(path string) (*fileopreate2.FoldersInfo, error) //获取文件或者文件夹基本信息
	GetFolderAll(dir, uname string, ctx context.Context) (*fileopreate2.FoldersInfo, error)
	FolderSize(path string, ctx context.Context) (int64, error)
	DelFolders(dirs ...string) error
	FolderRename(dir, rName, uname string, t ...int8) (*fileopreate2.FoldersInfo, error)
	FolderRenameFilter(dir, rName, uname string, t ...int8) (*fileopreate2.FoldersInfo, error)
	CreateFolderFilter(dir string, t int8, uname string) (*fileopreate2.FoldersInfo, error)
	MoveFiles(uname string, pa []string, outDir string, t fileopreate2.FileOperation, isSafeBox bool) (int64, error)
	StopAllMvOrCp(uname string) error
	CreateFolder(dir string, t int8) (*fileopreate2.FoldersInfo, error)
	VolumeUserQuota(path, uname string, size int64) bool
	GetFolderSize(path string, ctx context.Context) (uint8, int64, int, int)
	//SetRecentlyFunc(func(string, string))
	//SetSafeBox(safeBox file_safeBox.SafeBoxIn)
	GetBackgroundTaskLogs(uname string) ([]fileopreate2.BackgroundTaskLog, error)
	SetBackgroundTaskLogsMsg(uname string, totalSize int64, totalFile uint64, path string, size int64)
	GetBackgroundTaskLog(tid int64) *fileopreate2.BackgroundTaskLog
	StopBackgroundTask(data []string) error

	GetUserAuthority(path, user string) ([]string, error)
	ZipActualSize(zipSrc string, ctx context.Context, size, total *int64) error
	RunFileOperationTask(taskParams fileopreate2.TaskParams) (int64, error)

	GetHomeVolume() string
}

type FileOperate struct {
	db database.DbGetter
	//coreGetter  core2.ConfigGetter
	aclService  acl.FolderAttrService
	userService user.UserService
	//disk         disk.Getter
	taskArr      map[string]context.CancelFunc //保存cp和mv任务id
	sizeRWMutex  sync.RWMutex
	sizeTask     map[string]*CapacityStatistics //保存容量统计目录
	recentlyFunc func(string, string)           //文件复制或移动后，更新最近使用记录
	safeBox      file_safeBox.SafeBoxIn

	fileOperationTask    map[int64]*FileOperationTask //保存文件操作任务
	fileOperationRWMutex sync.RWMutex                 //保存文件操作任务读写锁
	fs                   afero.Fs
}

func New(db database.DbGetter,
	aclService acl.FolderAttrService,
	userService user.UserService,
	f afero.Fs) *FileOperate {
	return &FileOperate{
		db:          db,
		aclService:  aclService,
		userService: userService,
		//coreGetter:  configGetter,
		//disk:              disk,
		taskArr:           make(map[string]context.CancelFunc),
		sizeTask:          make(map[string]*CapacityStatistics),
		fileOperationTask: make(map[int64]*FileOperationTask),
		fs:                f,
	}
}

func (f *FileOperate) SetSafeBox(safeBox file_safeBox.SafeBoxIn) {
	f.safeBox = safeBox
}

func (f *FileOperate) SetRecentlyFunc(fn func(string, string)) {
	f.recentlyFunc = fn
}
